﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PojProject.Models;
using Algorithms;

namespace PojProject.Pojs
{
    public class Poj2965
    {
        ToggleButton[,] BtnMapping;
        int MaxRow, MaxCol;

        public Poj2965(ToggleButton[,] btnMapping)
        {
            this.BtnMapping = btnMapping;
            this.MaxRow = btnMapping.GetLength(0);
            this.MaxCol = btnMapping.GetLength(1);
        }

        private void PintToConsole(ToggleButton[,] btnMapping)
        {
            for (int i = 0; i < MaxRow; i++)
            {
                for (int j = 0; j < MaxCol; j++)
                {
                    var displayStr = btnMapping[i, j] == ToggleButton.Closed ? "+" : "-";
                    Console.Write(displayStr);
                }

                Console.WriteLine();
            }

            Console.WriteLine();
        }

        private ToggleButton[,] CopyToBtnMapping()
        {
            ToggleButton[,] copyMapping = new ToggleButton[MaxRow, MaxCol];

            for (int i = 0; i < MaxRow; i++)
            {
                for (int j = 0; j < MaxCol; j++)
                {
                    copyMapping[i, j] = BtnMapping[i, j];
                }
            }

            return copyMapping;
        }

        private List<int> RowColToMappingIndex()
        {
            List<int> ls = new List<int>();

            var m = MaxRow * MaxCol;

            for (int i = 0; i < m; i++)
            {
                ls.Add(i);
            }

            return ls;
        }

        public KeyValuePair<int, int> MappingIndexToRowCol(int mappingIndex)
        {
            int row = mappingIndex / MaxRow;
            int col = mappingIndex % MaxRow;

            return new KeyValuePair<int, int>(row, col);
        }

        private void ReverseBtn(ToggleButton[,] btnMapping, int row, int col)
        {
            btnMapping[row, col] = btnMapping[row, col] == ToggleButton.Closed ? ToggleButton.Opened : ToggleButton.Closed;
        }

        private void ReverseRelativeRowCol(ToggleButton[,] btnMapping, int row, int col)
        {
            var tempRow = row;
            while (tempRow > 0)
            {
                tempRow--;
                ReverseBtn(btnMapping, tempRow, col);
            }

            var tempRow1 = row;
            while (tempRow1 < MaxRow - 1)
            {
                tempRow1++;
                ReverseBtn(btnMapping, tempRow1, col);
            }

            var tempCol = col;
            while (tempCol > 0)
            {
                tempCol--;
                ReverseBtn(btnMapping, row, tempCol);
            }

            var tempCol1 = col;
            while (tempCol1 < MaxCol - 1)
            {
                tempCol1++;
                ReverseBtn(btnMapping, row, tempCol1);
            }
        }

        private bool IsWin(ToggleButton[,] btnMapping, ToggleButton targetType)
        {
            for (int i = 0; i < MaxRow; i++)
            {
                for (int j = 0; j < MaxCol; j++)
                {
                    if (btnMapping[i, j] != targetType)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public List<int> Play(ToggleButton targetChessType)
        {
            var mappingIndexes = RowColToMappingIndex();
            var al = new PermutationAndCombination<int>();
            for (int i = 1; i < MaxRow * MaxCol + 1; i++)
            {
                var co = al.GetCombination(mappingIndexes, i);

                foreach (var item in co)
                {
                    var copyMapping = CopyToBtnMapping();

                    foreach (var index in item)
                    {
                        var rowCol = MappingIndexToRowCol(index);
                        ReverseBtn(copyMapping, rowCol.Key, rowCol.Value);
                        ReverseRelativeRowCol(copyMapping, rowCol.Key, rowCol.Value);
                    }

                    if (IsWin(copyMapping, targetChessType))
                    {
                        return item;
                    }
                }
            }

            return null;
        }
    }
}
